﻿//Tzi Yong

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace Tzync
{
    public partial class FilterUIForm : Form
    {
        private SyncTool syncTool;
        private List<String> fileIncludeFilterList, fileExcludeFilterList, wildcardFilterList;
        private FilterIncOrEx isWildcardIncluded, isFileIncluded;    //toggle include/exclude
        private bool selectAllWildcard, selectAllFile; //toggle select/de-select

        public FilterUIForm(SyncTool newSyncTool, List<string> includeFileFiltersList, List<string> excludeFileFiltersList, List<string> wildcardFiltersList, FilterIncOrEx wildcardsIncluded)
        {
            fileIncludeFilterList = new List<string>();
            foreach (String s in includeFileFiltersList)
                fileIncludeFilterList.Add(s);

            fileExcludeFilterList = new List<string>();
            foreach (String s in excludeFileFiltersList)
                fileExcludeFilterList.Add(s);

            wildcardFilterList = new List<string>();
            foreach (String s in wildcardFiltersList)
                wildcardFilterList.Add(s);

            isWildcardIncluded = wildcardsIncluded;
            isFileIncluded = FilterIncOrEx.Included;

            selectAllWildcard = false;
            selectAllFile = false;

            syncTool = newSyncTool;
            InitializeComponent();

            if (isWildcardIncluded == FilterIncOrEx.Included)
                WildCardCB.SelectedIndex = 0;
            else
                WildCardCB.SelectedIndex = 1;

            DisplayFilters();               
        }

        private void FilterUIForm_Load(object sender, EventArgs e)
        {            
            fileCB.SelectedIndex = 0;
            infoLabel.Text = "";
          
            filterFolderBrowserDialog.SelectedPath = syncTool.GetRootAddress();

            backBtnToolTip.SetToolTip(backBtn, "Click here to return to Main");
            browseBtnToolTip.SetToolTip(browseFileBtn, "Click here to browse for a folder/file to filter");
            addFileBtnToolTip.SetToolTip(addFileBtn, "Click here to add to the list of filters");
            selectFileBtnToolTip.SetToolTip(selectAllFileBtn, "Click here to select or de-select all folders/files");
            removeFileBtnToolTip.SetToolTip(removeFileBtn, "Click here to Remove selected filter");
            selectWildcardBtnToolTip.SetToolTip(selectAllWildcardBtn, "Click here to select or de-select all wildcards");
            helpBtnToolTip.SetToolTip(helpBtn, "Click here to download our help file online!");
            aboutBtnToolTip.SetToolTip(aboutBtn, "Click here to learn more about Tzync and check for updates!");
        }

        private void FilterUIForm_Shown(object sender, EventArgs e)
        {
            infoLabel.Text = "";
            fileTB.Focus();
            DisplayFilters();
        }

        private void FilterUIForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.DialogResult = DialogResult.OK;
        }

        private void fileCB_SelectedIndexChanged(object sender, EventArgs e)
        {
            infoLabel.Text = "";
            if (fileCB.SelectedIndex == 0)
                isFileIncluded = FilterIncOrEx.Included;
            else
                isFileIncluded = FilterIncOrEx.Excluded;
        }

        private void FilterUIForm_DragEnter(object sender, DragEventArgs e)
        {
            infoLabel.Text = "";
            //only allow files/folders to be dropped here
            if (e.Data.GetDataPresent(DataFormats.FileDrop, false) == true)
                e.Effect = DragDropEffects.All;
        }

        private void FilterUIForm_DragDrop(object sender, DragEventArgs e)
        {
            infoLabel.Text = "";
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
        
            foreach (String filter in files)
            {
              
                if (!filter.Contains(syncTool.GetRootAddress()))
                    infoLabel.Text = "Please enter a folder/file path under the root folder!";
                else if (FindFile(filter, isFileIncluded) == true || syncTool.CheckIfAlreadyFiltered(filter, isFileIncluded) == FilterIncOrEx.AlreadyAdded)
                    infoLabel.Text = "Folder/File is already added! Please add another folder/file";
                else if (syncTool.CheckIfAlreadyFiltered(filter, isFileIncluded) == FilterIncOrEx.Included)
                    infoLabel.Text = "Folder/File is already included! Please add another folder/file";
                else if (syncTool.CheckIfAlreadyFiltered(filter, isFileIncluded) == FilterIncOrEx.Excluded)
                    infoLabel.Text = "Folder/File is already excluded! Please add another folder/file";
                else
                {
                    // To add Path filters
                    syncTool.AddPathFilter(filter, isFileIncluded);
                 
                    fileTB.Clear();
                    infoLabel.Text = "Folder/file filter added!";
                    fileTB.Focus();
                    DisplayFilters();
                }
            }

            DisplayFilters();
        }

        private void browseFileBtn_Click(object sender, EventArgs e)
        {
            infoLabel.Text = "";
            DialogResult result = filterFolderBrowserDialog.ShowDialog();
            if (result == DialogResult.OK)
                fileTB.Text = filterFolderBrowserDialog.SelectedPath;
            else
                return;
        }

        private void fileTB_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)13)
            {
                addFileBtn_Click(sender, e);
                fileTB.Clear();
                fileTB.Focus();
            }
        }

        private void addFileBtn_Click(object sender, EventArgs e)
        {
            #region Add WildCard Filter
            string filter = wildcardTB.Text;
            if (filter != "")
            {
                if (FindWildcard(filter) == true)
                    infoLabel.Text = "Wildcard is already added! Please select another wildcard";
                else
                {
                    syncTool.AddWildCardFilter(filter);
                    wildcardFilterList.Add(filter);
                    infoLabel.Text = "Filter(s) added!";
                    wildcardTB.Clear();
                }
                DisplayFilters();
                wildcardTB.Focus();
            }
            #endregion

            #region Add Path filters
            
            filter = fileTB.Text;
            if (filter != "")
            {
                if (!filter.Contains(syncTool.GetRootAddress()))
                    infoLabel.Text = "Please enter a valid folder/file path!";
                else if (FindFile(filter, isFileIncluded) == true ||
                         syncTool.CheckIfAlreadyFiltered(filter, isFileIncluded) == FilterIncOrEx.AlreadyAdded)
                    infoLabel.Text = "Folder/File is already added! Please add another folder/file";
                else if (syncTool.CheckIfAlreadyFiltered(filter, isFileIncluded) == FilterIncOrEx.Included)
                    infoLabel.Text = "Folder/File is already included! Please add another folder/file";

                else if (syncTool.CheckIfAlreadyFiltered(filter, isFileIncluded) == FilterIncOrEx.Excluded)
                    infoLabel.Text = "Folder/File is already excluded! Please add another folder/file";
                else
                {
                    // To add Path filters
                    syncTool.AddPathFilter(filter, isFileIncluded);

                    fileTB.Clear();
                    infoLabel.Text = "Filter(s) added!";
                    DisplayFilters();
                }

                fileTB.Focus();
            }

            #endregion

        }

        private void removeFileBtn_Click(object sender, EventArgs e)
        {
            #region Remove Path Filter
            infoLabel.Text = "";

            if (filterFileLV.CheckedItems.Count > 0)
            {
                ListViewItem filterItem = new ListViewItem();
                String filterType = "";
                String filter = "";

                for (int i = 0; i < filterFileLV.CheckedItems.Count; i++)
                {
                    filterItem = filterFileLV.CheckedItems[i];
                    filterType = filterItem.SubItems[1].Text;
                    filter = filterItem.Text;
                    //To Remove "root" string from the filter.
                    filter = filter.Substring(4);

                    if (filterType.Equals("Include"))
                    {
                        syncTool.RemovePathFilter(filter);
                        fileIncludeFilterList.Remove(filter);
                    }
                    else if (filterType.Equals("Exclude"))
                    {
                        syncTool.RemovePathFilter(filter);
                        fileExcludeFilterList.Remove(filter);
                    }
                }

                for (int i = 0; i < filterFileLV.Items.Count; i++)
                {
                    if (filterFileLV.Items[i].Checked == true)
                        filterFileLV.Items.Remove(filterFileLV.Items[i]);
                }
            }
            else
            {
                infoLabel.Text = "No folder/file filter(s) have been selected for removal!";
            }
            #endregion

            #region Remove Wild Card Filter
            infoLabel.Text = "";

            if (filterWildcardLV.CheckedItems.Count > 0)
            {
                ListViewItem filterItem = new ListViewItem();
                for (int i = 0; i < filterWildcardLV.CheckedItems.Count; i++)
                {
                    filterItem = filterWildcardLV.CheckedItems[i];
                    wildcardFilterList.Remove(filterItem.Text);
                    syncTool.RemoveWildCardFilter(filterItem.Text);
                }

                for (int i = 0; i < filterWildcardLV.Items.Count; i++)
                {
                    if (filterWildcardLV.Items[i].Checked == true)
                        filterWildcardLV.Items.Remove(filterWildcardLV.Items[i]);
                }
            }

            DisplayFilters();
            wildcardTB.Focus();
            infoLabel.Text = "Selected filter(s) have been removed!";
            #endregion
        }

        private void selectAllFileBtn_Click(object sender, EventArgs e)
        {
            infoLabel.Text = "";
            if (filterFileLV.Items.Count > 0)
            {
                if (!selectAllFile)
                {
                    foreach (ListViewItem item in filterFileLV.Items)
                        item.Checked = true;
                    selectAllFile = true;
                }
                else
                {
                    foreach (ListViewItem item in filterFileLV.Items)
                        item.Checked = false;
                    selectAllFile = false;
                }
            }
            else
                infoLabel.Text = "No folder/file filter(s) are available!";
        }

        private void wildcardTB_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)13)
            {
                addFileBtn_Click(sender, e);
                wildcardTB.Clear();
                wildcardTB.Focus();
            }
        }

        private void selectAllWildcardBtn_Click(object sender, EventArgs e)
        {
            infoLabel.Text = "";
            if (filterWildcardLV.Items.Count > 0)
            {
                if (!selectAllWildcard)
                {
                    foreach (ListViewItem item in filterWildcardLV.Items)
                        item.Checked = true;
                    selectAllWildcard = true;
                }
                else
                {
                    foreach (ListViewItem item in filterWildcardLV.Items)
                        item.Checked = false;
                    selectAllWildcard = false;
                }
            }
            else
                infoLabel.Text = "No wildcard filter(s) are available!";
        }

        private void applyBtn_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void cancelBtn_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        //displays added filters
        private void DisplayFilters()
        {
            ListViewItem filterItem;
            filterFileLV.Items.Clear();
            filterWildcardLV.Items.Clear();

            //Reads from filter metadata
            RefreshFilterList();

            for (int i = 0; i < fileIncludeFilterList.Count; i++)
            {
                filterItem = new ListViewItem();
                filterItem.Text = "root"+fileIncludeFilterList[i];
                filterItem.SubItems.Add("Include");
                filterFileLV.Items.Add(filterItem);
            }

            for (int i = 0; i < fileExcludeFilterList.Count; i++)  
            {
                filterItem = new ListViewItem();
                filterItem.Text = "root"+fileExcludeFilterList[i];
                filterItem.SubItems.Add("Exclude");
                filterFileLV.Items.Add(filterItem);
            }

            for (int i = 0; i < wildcardFilterList.Count; i++)
            {
                filterItem = new ListViewItem();
                filterItem.Text = wildcardFilterList[i];
                filterWildcardLV.Items.Add(filterItem);
            }

            Utility.ResizeColumns(filterFileLV);
            Utility.ResizeColumns(filterWildcardLV);
        }

        private void aboutBtn_Click(object sender, EventArgs e)
        {
            AboutUIForm aboutUI = new AboutUIForm();
            aboutUI.ShowDialog();
        }

        private void helpBtn_Click(object sender, EventArgs e)
        {
            infoLabel.Text = "";
            Process.Start("http://tzync.googlecode.com/files/Tzync_User_Guide_V2.pdf");
        }

        private void backBtn_Click(object sender, EventArgs e)
        {
            syncTool.SetWildCardIncOrEx(isWildcardIncluded);
            syncTool.WriteToFilterFile();   //write to filter metadata
            this.Close();
        }

        private void WildCardCB_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (WildCardCB.SelectedIndex == 0)
                isWildcardIncluded = FilterIncOrEx.Included;
            else
                isWildcardIncluded = FilterIncOrEx.Excluded;
        }

        /// <summary>
        /// Refreshes list of filters by reading from metadata
        /// </summary>
        private void RefreshFilterList()
        {
            fileExcludeFilterList.Clear();
            foreach (String s in syncTool.GetExcludePathFilters())
                fileExcludeFilterList.Add(s);

            fileIncludeFilterList.Clear();
            foreach (String s in syncTool.GetIncludePathFilters())
                fileIncludeFilterList.Add(s);
        }

        /// <summary>
        /// Checks if a file or folder has already been added to the list of filters
        /// </summary>
        private bool FindFile(String file, FilterIncOrEx type)
        {
            if (type == FilterIncOrEx.Included)
            {
                foreach (String f in fileIncludeFilterList)
                {
                    if (f.Equals(file) == true)
                        return true;
                }
            }
            else
            {
                foreach (String f in fileExcludeFilterList)
                {
                    if (f.Equals(file) == true)
                        return true;
                }
            }

            return false;
        }

        /// <summary>
        /// Checks if a wildcard has already been added to the list filters
        /// </summary>
        private bool FindWildcard(String wildcard)
        {
            foreach (String w in wildcardFilterList)
            {
                if (w.Equals(wildcard) == true)
                    return true;
            }

            return false;
        }
    }
}
